package extract;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

import javax.swing.plaf.basic.BasicInternalFrameTitlePane.MoveAction;

public class Test {
	static List<MovieObj> movies=new LinkedList<MovieObj>();


	/**
	 * @param args
	 */
	public static void main(String[] args) {
		//Jinni jinni=new Jinni();
		//jinni.read2();
		//jinni.run();

		//IMDb imdb=new IMDb();
		//imdb.read();

		generateMovies();

		generateDistanceMatrix();
		
		/*	Here is the KNN and predict rating 	*/
		List<MovieObj>movie_knn =K_Nearest_Neighbour(0, 4);
		for(MovieObj o:movie_knn){
			System.out.println("name: "+o.name);
			System.out.println("value: "+o.kNNValue);
		}
		System.out.println("rating: "+predictRating(movie_knn));
	}


	private static void generateDistanceMatrix() {
		FileWriter fw;
		BufferedWriter bw;
		try {
			fw=new FileWriter("matrix.txt");
			bw=new BufferedWriter(fw);

			String s="";
			//For headers
			for(int i=0;i<movies.size();i++){
				s+=" "+movies.get(i).name;
			}
			bw.write(s+"\n");
			
			for(int i=0;i<movies.size();i++){
				s=movies.get(i).name;

				K_Nearest_Neighbour(i, 1);
/*				for(MovieObj o:movies){
					s+=" "+o.kNNValue;
				}*/
				for(int j=0;j<movies.size();j++){
					s+=" "+movies.get(j).kNNValue;
				}
				bw.write(s+"\n");
			}
			
			bw.close();
			fw.close();

		} catch (IOException e) {
			e.printStackTrace();
		}
	}


	private static void generateMovies() {
		try {
			FileReader reader=new FileReader("dataset.txt");
			BufferedReader br=new BufferedReader(reader);
			MovieObj movie=null;
			for(int i=0;br.ready();i++){
				String line=br.readLine();
				try{
					switch(i%11){
					case 0:
						movie=new MovieObj();
						movie.name=line.substring(12);	//get rid of "Movie Name: "
						for(MovieObj obj:movies){
							if (obj.name.equals(movie.name))
								movie.toDiscard=true;							
						}
						break;
					case 1:
						for(String s: line.substring(6).split(","))
						{
							movie.stars.add(s);
						}
						break;
					case 2:
						for(String s:line.substring(10).split(",")){
							movie.directors.add(s);
						}
						break;
					case 3:
						for(String s:line.substring(8).split(",")){
							movie.writers.add(s);
						}
						break;
					case 4:
						movie.rating=Double.valueOf(line.substring(7, 10));
						if (movie.rating<7.0)	
							movie.toDiscard=true;
						break;
					case 5:
						for(String s:line.substring(5).split(",")){
							movie.mood.add(s);
						}
						break;
					case 6:
						for(String s:line.substring(5).split(",")){
							movie.plot.add(s);
						}
						break;
					case 7:
						for(String s:line.substring(7).split(",")){
							movie.genres.add(s);
						}
						break;
					case 8:
						for(String s:line.substring(9).split(",")){
							movie.audience.add(s);
						}
						break;
					case 9:
						for(String s:line.substring(9).split(",")){
							movie.similars.add(s);
						}
						break;
					case 10:
						if(!movie.toDiscard)
							movies.add(movie);
						break;
					}
				}catch(Exception e){
					//System.out.println("err: "+i);
					movie.toDiscard=true;
				}
			}
			br.close();
			reader.close();

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private static List<MovieObj> K_Nearest_Neighbour(int index,int k){
		MovieObj movie=movies.get(index);

		for(int i=0;i<movies.size();i++){
			int value=0;
			MovieObj movie_cmp=movies.get(i);

			if (i==index)	
			{
				movie_cmp.kNNValue=value;
				movies.set(i, movie_cmp);
				continue;
			}

			for(String s:movie.directors){
				if (movie_cmp.directors.contains(s))
					value+=1;
			}
			for(String s:movie.stars){
				if (movie_cmp.stars.contains(s))
					value+=1;				
			}
			for(String s:movie.writers){
				if (movie_cmp.writers.contains(s))
					value+=1;
			}
			for(String s:movie.genres){
				if (movie_cmp.genres.contains(s))
					value+=5;
			}
			for(String s:movie.mood){
				if (movie_cmp.mood.contains(s))
					value+=5;
			}
			for(String s:movie.plot){
				if	(movie_cmp.plot.contains(s))
					value+=5;
			}
			for(String s:movie.audience){
				if (movie_cmp.audience.contains(s))
					value+=1;
			}

			movie_cmp.kNNValue=value;
			//movie_cmp.distance=200/(value+1);
			movies.set(i, movie_cmp);
		}

		List<MovieObj> temp=new ArrayList<MovieObj>(movies);
		
		Collections.copy(temp, movies);
		
		Collections.sort(temp);
		Collections.reverse(temp);
		return temp.subList(0, k);
	}

	private static double predictRating(List<MovieObj> movie_knn){
		double avg=0,totalweight=0;
		for(MovieObj o:movie_knn){
			avg+=o.kNNValue*o.rating;
			totalweight+=o.kNNValue;
		}
		return avg/totalweight;
	}
}
